﻿// Copyright (c) Canaan Inc. All rights reserved.
// Licensed under the Apache license. See LICENSE file in the project root for full license information.

namespace Nncase.TIR
{
    /// <summary>
    /// the tir attrubute.
    /// </summary>
    [System.Flags]
    public enum Attr : long
    {
        /// <summary>
        /// no attr.
        /// </summary>
        None = 0,

        /// <summary>
        /// Mark launching extent of thread, used by device API.
        /// </summary>
        Thread_extent = 1,

        /// <summary>
        /// Mark launching of a virtual thread.
        /// </summary>
        Virtual_thread = 2,

        /// <summary>
        /// Mark region is processed by a co-proccesor.
        /// </summary>
        Coproc_scope = 4,

        /// <summary>
        /// Mark region creates coprocessor micro ops,
        ///  can be reused if corresponding variable is independent.
        /// </summary>
        Coproc_uop_scope = 8,

        /// <summary>
        /// Mark the scope as volatile access for certain handle.
        /// </summary>
        Volatile_scope = 16,

        /// <summary>
        /// Mark the scope as generated by extern primitive.
        ///  such scope can contain arbitrary ir program and we need to be careful
        ///  when make certain assumptions about the structure of the program.
        /// </summary>
        Extern_scope = 32,

        /// <summary>
        /// Mark the scope as when computation start to happen
        ///  This can hint some code generator to create a new function for compute.
        /// </summary>
        Compute_scope = 64,

        /// <summary>
        /// Mark storage alignement requirement of buffers.
        /// </summary>
        Storage_alignment = 128,

        /// <summary>
        /// Mark storage scope of realization.
        /// </summary>
        Realize_scope = 256,

        /// <summary>
        /// The allocation device for global malloc in host.
        /// </summary>
        Device_id = 512,

        /// <summary>
        /// The device type.
        /// </summary>
        Device_type = 1024,

        /// <summary>
        /// Mark of loop scope.
        /// </summary>
        Loop_scope = 2048,

        /// <summary>
        /// Mark of reduce scope.
        /// </summary>
        Reduce_scope = 4096,

        /// <summary>
        /// Mark region is guarded by the pragma extension.
        /// </summary>
        Pragma_scope_prefix = 8192,

        /// <summary>
        /// Import C source or file into the final code gen module.
        /// </summary>
        Pragma_import_c = 16384,

        /// <summary>
        /// Import llvm source or file into the final code gen module.
        /// </summary>
        Pragma_import_llvm = 32768,

        /// <summary>
        /// Try to modify the AST to support Tensor Core.
        /// </summary>
        Pragma_tensor_core = 65536,

        /// <summary>
        /// Mark of prefetch scope, value,
        ///  run prefetch of Tensor on the current loop scope.
        /// </summary>
        Prefetch_scope = 131072,

        /// <summary>
        /// Marks production of double buffer data.
        /// </summary>
        Double_buffer_scope = 262144,

        /// <summary>
        /// Marks region used by double buffer write.
        /// </summary>
        Double_buffer_write = 524288,

        /// <summary>
        /// Mark of scan update scope.
        /// </summary>
        Scan_update_scope = 1048576,

        /// <summary>
        /// Mark of scan init scope.
        /// </summary>
        Scan_init_scope = 2097152,

        /// <summary>
        /// Mark alignment of buffer dimension
        ///  stmt.node is Tensor
        ///  stmt.value is tvm_tuple(dim, align, offset)
        ///  This gives hint to require stride of dim to be k * align + offset.
        /// </summary>
        Buffer_dim_align = 4194304,

        /// <summary>
        /// Mark stores/loads with theirs bounds.
        /// </summary>
        Buffer_bound = 8388608,

        /// <summary>
        /// Bind the buffer specification to the region of the op
        ///  When this scope occurs, the stmt.node is a IRArray.{NodeRef} ,
        ///  stmt.value is a tvm_tuple(min0, extent0, min1, extent1, ...).
        ///  The scope represents that we need to bind the storage region of tensor to buffer.
        ///  This will affect replacement of some variables inside the scope that
        ///  corresponds to field of buffer to be the actual expressions of tensor during
        ///  storage flattening phase.
        /// </summary>
        Buffer_bind_scope = 16777216,

        /// <summary>
        /// channel read scope.
        /// </summary>
        Channel_read_scope = 33554432,

        /// <summary>
        /// Advance step of channel after end of scope.
        /// </summary>
        Channel_read_advance = 67108864,

        /// <summary>
        /// channel write scope.
        /// </summary>
        Channel_write_scope = 134217728,

        /// <summary>
        /// Advance step of channel after end of scope.
        /// </summary>
        Channel_write_advance = 268435456,

        /// <summary>
        /// pipeline stage scope, implies always execution.
        /// </summary>
        Pipeline_stage_scope = 536870912,

        /// <summary>
        /// pipeline execution scope, implies the scope can be pipelined.
        /// </summary>
        Pipeline_exec_scope = 1073741824,

        /// <summary>
        /// Mark that it is in the device scope.
        /// </summary>
        Device_scope = 2147483648,

        /// <summary>
        /// Mark that the shape of TensorCore fragment.
        /// </summary>
        Fragment_shape = 4294967296,

        /// <summary>
        /// Mark that the layout of TensorCore fragment.
        /// </summary>
        Fragment_layout = 8589934592,

        /// <summary>
        /// Mark that the kernel is hand threaded and doesn't need syncs inserted.
        /// </summary>
        Hand_threaded = 17179869184,

        /// <summary>
        /// Mark whether the script-completer need to fill in missing access region
        /// during script parsing.
        /// <remarks>
        /// The result should be a integer mask with range [0, 4).
        /// if (mask and 1) the read region should be detected,
        /// if (mask and 2) the write region should be detected.
        /// </remarks>
        /// </summary>
        Script_parsing_detect_access = 34359738368,

        /// <summary>
        /// Mark that the loop should be partitioned.
        /// </summary>
        Pragma_loop_partition_hint,

        /// <summary>
        /// List of thread IterVar that a DeviceLaunch function corresponds to.
        ///
        /// Type: Array.{tir::IterVar}
        ///
        /// We call a device kernel launch function f using the following convention:
        ///
        /// Call(f,
        ///      [arg1, arg2, ..., arg_n,
        ///       work_size_1, work_size_2, ... work_size_m, dyn_shmem_size])
        ///
        /// Here n ,(device_thread_axis).
        ///
        /// When kDeviceUseDynSharedMemory is not set, dyn_shmem_size argument is omitted.
        ///
        /// The list of device_thread_axis indicates how can be bind the
        /// work_size arguments to the corresponding threads.
        /// </summary>
        DeviceThreadAxis = 68719476736,

        /// <summary>
        /// Whether or not use dynamic shared memory.
        /// </summary>
        DeviceUseDynSharedMemory = 137438953472,

        /// <summary>
        /// Whether to set noalias rule on the function arguments.
        /// </summary>
        NoAlias = 274877906944,

        /// <summary>
        /// Mark the function as the entry function of the final generated runtime module.
        /// </summary>
        IsEntryFunc = 549755813888,

        /// <summary>
        /// Arguments used in the module that should be linked by the codegen.
        /// </summary>
        LinkedParams = 1099511627776,

        /// <summary>
        /// Mark the function as the global function called from the host.
        /// </summary>
        IsGlobalFunc = 2199023255552,
    }
}
